package com.kakarote.ids.provider.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.kakarote.common.entity.UserInfo;
import com.kakarote.common.exception.BusinessException;
import com.kakarote.common.redis.Redis;
import com.kakarote.common.result.Result;
import com.kakarote.ids.provider.common.Const;
import com.kakarote.ids.provider.common.OAuthProperties;
import com.kakarote.ids.provider.entity.VO.TokenVO;
import com.kakarote.ids.provider.service.AuthService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class AuthServiceImpl implements AuthService {
    private static final Logger log = LoggerFactory.getLogger(AuthServiceImpl.class);

    @Autowired
    private OAuthProperties properties;

    @Autowired
    private Redis redis;

    public String authorization(String code) {
        HttpRequest request = HttpUtil.createPost(Const.GET_TOKEN_URI);
        JSONObject object = new JSONObject();
        object.put("clientId", this.properties.getClientId());
        object.put("clientSecret", this.properties.getClientSecret());
        object.put("redirectUri", this.properties.getRedirectUri());
        object.put("scope", "user");
        object.put("grantType", "code");
        object.put("code", code);
        try {
            request.body(object.toJSONString());
            HttpResponse execute = request.execute();
            JSONObject body = JSON.parseObject(execute.body());
            Result<TokenVO> result = Result.of(body.getInteger("code").intValue(), body.getString("msg"));
            if (result.hasSuccess()) {
                TokenVO data = body.getObject("data", TokenVO.class);
                result.setData(data);
                String key = IdUtil.simpleUUID();
                this.redis.setex(key + Const.TOKEN_CACHE_NAME, Integer.valueOf(Const.REFRESH_TOKEN_EXPIRE_TIME), data);
                getLoginUser(data, key);
                return key;
            }
        } catch (Exception e) {
            log.error("授权错误", e);
        }
        return null;
    }

    public void logout(String token) {
        HttpRequest request = HttpUtil.createPost(Const.LOGOUT_URI);
        TokenVO tokenVO = this.redis.get(token + Const.TOKEN_CACHE_NAME);
        try {
            request.body(JSON.toJSONString(tokenVO));
            request.execute();
        } catch (Exception e) {
            log.error("授权错误", e);
        }
        this.redis.del(token, token + Const.TOKEN_CACHE_NAME);
    }

    private void getLoginUser(TokenVO data, String key) {
        HttpRequest request = HttpUtil.createPost(Const.GET_USER_URI);
        request.header("Authorization", "Bearer " + data.getAccessToken());
        HttpResponse execute = request.execute();
        JSONObject body = JSON.parseObject(execute.body());
        Result<TokenVO> result = Result.of(body.getInteger("code").intValue(), body.getString("msg"));
        if (result.hasSuccess()) {
            UserInfo userInfo = body.getObject("data", UserInfo.class);
            this.redis.setex(key, Integer.valueOf(Const.REFRESH_TOKEN_EXPIRE_TIME), userInfo);
        } else {
            throw new BusinessException(result.getCode(), result.getMsg());
        }
    }
}
